#ifndef COMMON_VEC4_H
#define COMMON_VEC4_H

#include "Common/Algebra/Misc.h"
#include "Common/Algebra/Vec2.h"
#include "Common/Algebra/Vec3.h"

class Vec4 {
public:
	float X, Y, Z, W;

	Vec4( float x, float y, float z, float w ) : X( x ), Y( y ), Z( z ), W( w ) {
	}

	Vec4( const Vec3& vec, float w ) : X( vec.X ), Y( vec.Y ), Z( vec.Z ), W( w ) {
	}

	Vec4( const Vec2& vec, float z, float w ) : X( vec.X ), Y( vec.Y ), Z( z ), W( w ) {
	}

	Vec4 operator +=(const Vec4& v );
	Vec4 operator -=(const Vec4& v );
	Vec4 operator *=(float a);
	Vec4 operator /=(float a);

	inline float Len( ) const {
		return (float) sqrt( Norm( ) );
	}

	inline float Norm( ) const {
		return (float) ( X * X + Y * Y + Z * Z + W * W );
	}

	Vec4 Normalize( );

	static const Vec4 ZERO_VEC;
	static const Vec4 ZERO_POINT;

	static const Vec4 UP;
	static const Vec4 DOWN;
	static const Vec4 LEFT;
	static const Vec4 RIGHT;
	static const Vec4 FORWARD;
	static const Vec4 BACK;

};

inline Vec4 operator-(const Vec4& v ) {
	return Vec4( -v.X, -v.Y, -v.Z, -v.W );
}

inline Vec4 operator+(const Vec4& a, const Vec4& b ) {
	return Vec4( a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W );
}

inline Vec4 operator-(const Vec4& a, const Vec4& b ) {
	return Vec4( a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W );
}

inline Vec4 operator*(const Vec4& v, float a) {
	return Vec4( v.X * a, v.Y * a, v.Z * a, v.W * a );
}

inline Vec4 operator/(const Vec4& v, float a) {
	return Vec4( v.X / a, v.Y / a, v.Z / a, v.W / a );
}

inline Vec4 operator^ (const Vec4& a, const Vec4& b ) {
	return Vec4( a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X, a.W );
}

inline float operator*(const Vec4& a, const Vec4& b ) {
	return a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W;
}
#endif
